package com.excel.validators.core.decorative;


import java.util.Iterator;

import com.excel.validators.core.decorative.inner.IErrorMessage;
import com.excel.validators.log.Log;
import com.excel.validators.log.LogFactory;

/**
 * @author wangxiaoliang10
 * 不支持多线程迭代操作
 */
@SuppressWarnings({"rawtypes","unchecked"})
public class CompositeValue implements IErrorMessage,Iterable<FieldValue> {

	// single looger
	protected static final Log logger = LogFactory.getLog(CompositeValue.class);
	
	/**
	 * audio object
	 */
	private FieldValue[] fields;
	
	private int index;

	private AuditIterator iterator;
	
	protected FieldValue[] getValues() {
			return fields;
	}
	
	protected FieldValue getField(int index) {
			if (index < 0 || 
					index > fields.length) {
					throw new ArrayIndexOutOfBoundsException("can not find Column field, index: " + index);
			}
			return fields[index];
	}
	
	public CompositeValue(int initialCapacity) {
			this.fields = new FieldValue[initialCapacity];
	}
	
	/**
	 * 受检列表,列表只加不减
	 * @param liveExpression
	 * @throws IllegalAccessException
	 */
	public void addChild(FieldValue fieldValue) {
			if (index > fields.length)
					throw new ArrayIndexOutOfBoundsException("can not add more audit field");
			fields[index++] = fieldValue;
	}

	@Override
	public boolean hasError() {
			for (FieldValue fieldValue : fields) {
					if (fieldValue.hasError()) {
							return true;
					}
			}
			return false;
	}

	@Override
	public String getMessage() {
			StringBuilder builder = null;
			for (FieldValue fieldValue : fields) {
					if (fieldValue.hasError()) {
							if (builder == null) {
									builder = new StringBuilder();
							}
							builder.append(fieldValue.getMessage());
					}
			}
			String message = builder != null ? builder.toString() : null;
			if (logger.isTraceEnabled()) {
					logger.info(message);
			}
			return message;
	}

	@Override
	public Iterator<FieldValue> iterator() {
			if (iterator == null) {
					iterator = new AuditIterator();
			}
			return iterator.reset();
	}
	
	@Override
	public String toString() {
			StringBuilder builder = new StringBuilder("CompositeValue {");
			for (FieldValue fieldValue : fields) {
					builder.append(fieldValue.getFieldName());
					builder.append("=");
					builder.append(fieldValue.getValue());
					builder.append(" ,");
			}
			builder.deleteCharAt(builder.length() - 1);
			builder.append("}");
			return builder.toString();
	}

	final class AuditIterator implements java.util.Iterator<FieldValue> {

		/**
			 * next and hasNext index
			 */
			private transient int index = 0;
			
			/**
			 * 重置index
			 */
			protected Iterator reset() {
					index = 0;
					return this;
			}
			
			@Override
			public boolean hasNext() {
					int hasIndex = index & 0x00ff;
					if (hasIndex >= fields.length)
							return false;
					for (int i = hasIndex; i < fields.length; i++) {
							if (fields[i] != null) {
									index = (i << 8) ^ (++i);
									return true;
							}
					}
					index = fields.length ^ (fields.length << 8);
					return false;
			}
	
			@Override
			public FieldValue next() {
					int nextIndex = index >>> 8;
					if (nextIndex >= fields.length)
							throw new UnsupportedOperationException();
					return fields[nextIndex];
			}

	}
}
